package com.jw.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jw.handler.BusinessException;
import com.jw.response.ResultCode;
import com.jw.system.entity.*;
import com.jw.system.entity.vo.GoodsOutVO;
import com.jw.system.entity.vo.GoodsVO;
import com.jw.system.entity.vo.UserVO;
import com.jw.system.mapper.*;
import com.jw.system.service.GoodsOutService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * <p>
 * 商品出库表 服务实现类
 * </p>
 *
 * @author jw
 * @since 2021-04-28
 */
@Service
public class GoodsOutServiceImpl extends ServiceImpl<GoodsOutMapper, GoodsOut> implements GoodsOutService {

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ContractMapper contractMapper;

    @Autowired
    private ConGoodsMapper conGoodsMapper;

    @Autowired
    private GoodsOutMapper goodsOutMapper;

    @Autowired
    private OutInfoMapper outInfoMapper;

    @Override
    public Page<GoodsOutVO> getGoodsOutList(Integer current, Integer size, Boolean audit, GoodsOutVO goodsOutVO) {
        Page<GoodsOut> page = new Page<>(current, size);
        List<Long> list = new ArrayList<>();
        QueryWrapper<GoodsOut> queryWrapper = new QueryWrapper();
        QueryWrapper<User> queryUser = new QueryWrapper();
        if (goodsOutVO.getUsername() != null) {
            queryUser.like("username", goodsOutVO.getUsername());
            List<User> users = userMapper.selectList(queryUser);
            if (!users.isEmpty()) {
                for (User user : users) {
                    list.add(user.getId());
                }
                queryWrapper.in("user_id", list);
            } else {
                return new Page<>();
            }
        }
        if(goodsOutVO.getConNum()!=null){
            QueryWrapper<Contract> queryCon = new QueryWrapper();
            queryCon.like("con_num",goodsOutVO.getConNum());
            List<Contract> contracts = contractMapper.selectList(queryCon);
            List<Long> conIdList = new ArrayList<>();
            if (!contracts.isEmpty()) {
                for (Contract contract : contracts) {
                    conIdList.add(contract.getId());
                }
                queryWrapper.in("con_id", conIdList);
            } else {
                return new Page<>();
            }
        }
        if (goodsOutVO.getOutNum() != null) {
            queryWrapper.like("out_num", goodsOutVO.getOutNum());
        }
        if (goodsOutVO.getStartTime() != null) {
            queryWrapper.ge("in_date", goodsOutVO.getStartTime());
            queryWrapper.le("in_date", goodsOutVO.getEndTime());
        }
        if (goodsOutVO.getStaus() != null) {
            queryWrapper.eq("staus", goodsOutVO.getStaus());
        }
        if(audit){
            queryWrapper.eq("staus", 0);
        }
        Page<GoodsOut> goodsOutPage = goodsOutMapper.selectPage(page, queryWrapper);
        List<GoodsOut> goodsOuts = goodsOutPage.getRecords();

        List<GoodsOutVO> goodsOutVOS = new ArrayList<>();
        for (GoodsOut goodsOut : goodsOuts) {
            GoodsOutVO goodsOutVO1 = new GoodsOutVO();
            BeanUtils.copyProperties(goodsOut, goodsOutVO1);
            User user = userMapper.selectById(goodsOut.getUserId());
            goodsOutVO1.setUsername(user.getUsername());
            User user2 = userMapper.selectById(goodsOut.getAuditorId());
            goodsOutVO1.setAuditorName(user2.getUsername());
            goodsOutVO1.setConNum(contractMapper.selectById(goodsOut.getConId()).getConNum());
            goodsOutVOS.add(goodsOutVO1);
        }
        Page<GoodsOutVO> goodsOutVOPage = new Page<>();
        goodsOutVOPage.setRecords(goodsOutVOS);
        goodsOutVOPage.setTotal(goodsOutPage.getTotal());
        return goodsOutVOPage;
    }

    @Override
    public void add(GoodsOutVO goodsOutVO) {
        {
            //随机生成发货单号
            String OUT_STOCK_NUM = UUID.randomUUID().toString().substring(0, 16).replace("-", "");

            List<Object> products = goodsOutVO.getProducts();

            if (!CollectionUtils.isEmpty(products)) {
                for (Object product : products) {
                    LinkedHashMap item = (LinkedHashMap) product;
                    //发货数量
                    int productNumber = (int) item.get("productNumber");
                    //商品id
                    Integer productId = (Integer) item.get("productId");
                    Goods dbProduct = goodsMapper.selectById(productId);
                    if (dbProduct == null) {
                        throw new BusinessException(ResultCode.PRODUCT_NOT_FOUND.getCode(),
                                ResultCode.PRODUCT_NOT_FOUND.getMessage());
                    } else if (productNumber <= 0) {
                        throw new BusinessException(ResultCode.PRODUCT_OUT_STOCK_NUMBER_ERROR.getCode(),
                                ResultCode.PRODUCT_OUT_STOCK_NUMBER_ERROR.getMessage());
                    } else {
                        //插入发货单明细
                        OutInfo outStockInfo = new OutInfo();
                        outStockInfo.setOutNum(OUT_STOCK_NUM);
                        outStockInfo.setGoodsId(dbProduct.getId());
                        outStockInfo.setNum(productNumber);
                        outInfoMapper.insert(outStockInfo);
                    }
                }

                GoodsOut GoodsOut = new GoodsOut();
                GoodsOut.setOutDate(new Date());
                GoodsOut.setUserId(goodsOutVO.getUserId());
                GoodsOut.setAuditorId(goodsOutVO.getAuditorId());
                GoodsOut.setStaus(0);
                GoodsOut.setConId(goodsOutVO.getConId());
                GoodsOut.setRemark(goodsOutVO.getRemark());
                GoodsOut.setOutNum(OUT_STOCK_NUM);
                GoodsOut.setName(goodsOutVO.getName());
                GoodsOut.setAddress(goodsOutVO.getAddress());
                GoodsOut.setPhone(goodsOutVO.getPhone());
                goodsOutMapper.insert(GoodsOut);
            } else {
                throw new BusinessException(ResultCode.PRODUCT_OUT_STOCK_EMPTY.getCode(),
                        ResultCode.PRODUCT_OUT_STOCK_EMPTY.getMessage());
            }

        }
    }

    @Override
    public void finish(GoodsOutVO goodsOutVO) {
        GoodsOut goodsOut = goodsOutMapper.selectById(goodsOutVO.getId());
        goodsOut.setStaus(2);
        goodsOut.setCourierNum(goodsOutVO.getCourierNum());
        goodsOut.setCourierCompany(goodsOutVO.getCourierCompany());
        goodsOutMapper.updateById(goodsOut);

        Contract contract = contractMapper.selectById(goodsOutVO.getConId());
        QueryWrapper<ConGoods> queryConGoods = new QueryWrapper();
        queryConGoods.eq("con_num",contract.getConNum());
        List<ConGoods> conGoods = conGoodsMapper.selectList(queryConGoods);
        for(ConGoods c : conGoods){
            QueryWrapper<OutInfo> outInfoQueryWrapper = new QueryWrapper();
            outInfoQueryWrapper.eq("out_num",goodsOut.getOutNum());
            outInfoQueryWrapper.eq("goods_id",c.getGoodsId());
            OutInfo outInfo = outInfoMapper.selectOne(outInfoQueryWrapper);
            if(outInfo!=null){
                c.setFinishNum(c.getFinishNum()+outInfo.getNum());
                QueryWrapper<ConGoods> conGoodsQueryWrapper = new QueryWrapper();
                conGoodsQueryWrapper.eq("con_num",c.getConNum());
                conGoodsQueryWrapper.eq("goods_id",c.getGoodsId());
                if(c.getFinishNum()>=c.getOrderNum()){
                    c.setStaus(2);
                }
                else {
                    c.setStaus(1);
                }
                conGoodsMapper.update(c,conGoodsQueryWrapper);
            }
        }
        //更新合同状态
        List<ConGoods> conGoodsNew = conGoodsMapper.selectList(queryConGoods);
        int flag =0;
        for(ConGoods conGoods1:conGoodsNew){
            if(conGoods1.getStaus()!=2){
                flag=1;
                break;
            }
        }
        if(flag==0){
            contract.setStaus(2);
            contract.setFinishDate(new Date());
        }
        else{
            contract.setStaus(1);
        }
        contractMapper.updateById(contract);

    }

    @Override
    public void getApprove(Long id) {
        GoodsOut goodsOut = goodsOutMapper.selectById(id);
        goodsOut.setStaus(1);
        goodsOutMapper.updateById(goodsOut);
    }

    @Override
    public Page<GoodsVO> getDetail(Integer current, Integer size, Long id) {
        Page<OutInfo> page = new Page<>(current, size);
        QueryWrapper<OutInfo> queryWrapper = new QueryWrapper();
        GoodsOut goodsOut = goodsOutMapper.selectById(id);
        queryWrapper.eq("out_num", goodsOut.getOutNum());
        Page<OutInfo> outInfoPage = outInfoMapper.selectPage(page, queryWrapper);

        List<GoodsVO> goodsList = new ArrayList<>();
        for (OutInfo outInfo : outInfoPage.getRecords()) {
            GoodsVO goodsVO = new GoodsVO();
            Goods goods = goodsMapper.selectById(outInfo.getGoodsId());
            BeanUtils.copyProperties(goods, goodsVO);
            goodsVO.setOrderNum(outInfo.getNum());
            goodsList.add(goodsVO);
        }
        Page<GoodsVO> goodsPage = new Page<>();
        goodsPage.setRecords(goodsList);
        goodsPage.setTotal(outInfoPage.getTotal());
        return goodsPage;
    }
}
